---
title: AdminController
summary: Three POST endpoints that return the raw credential parts and composed connection string for a named database target.
status: draft
owner: Architecture
last_reviewed: 2026-10-09
---

# AdminController

`AdminController` exposes three credential-inspection endpoints, one per database type. Each reads the secure credential directly from the SAIF Environment API and returns the user name, the plaintext password and the composed connection string in a JSON object. It performs no existence check, no connectivity probe, no caching and no audit logging. These endpoints return credential material and are flagged CRITICAL (see [Authentication and authorization](../authentication-authorization.md#security-findings)). Callers are not determined from source**.

| Field | Value |
| --- | --- |
| **Controller** | `AdminController` |
| **Base** | `ControllerBase` |
| **`[ApiController]`** | Applied |
| **Route template** | `v1/Admin` followed by the action name (the controller-name token resolves to `Admin`) |
| **API version** | Literal route prefix `v1` (no API versioning) |
| **Source** | `DBConnectionAPI/DBConnectionAPI/Controllers/AdminController.cs` |
| **Controller-level authorization** | `[SecurityApiAuthorize("DBConnAPIRetrieveResource")]` |
| **Error handling** | Local bare `try`/`catch` around the credential split that swallows the exception ([BR-DBC-024](../business-rules.md#br-dbc-024-admin-split-failure-reported-with-status-200)); other exceptions flow to opaque package middleware** |
| **Endpoints** | 3 |

The `protected` helper `GetConnectionInfo(string, string)` is not an action and is not routable.

---

## POST v1 Admin GetOracleConnectionInfo

Returns the decrypted credential parts and the composed connection string for an Oracle instance and user name.

| Field | Value |
| --- | --- |
| **HTTP verb** | `POST` |
| **Resolved route** | `/v1/Admin/GetOracleConnectionInfo` |
| **Route composition** | Class-level `[Route]` template + bare `[HttpPost]`, with the controller-name token resolved to `Admin` and the action token to `GetOracleConnectionInfo` |
| **Action** | `GetOracleConnectionInfo` |
| **Return type** | `Dictionary<string, string>` |
| **Declared responses** | None |
| **Authorization** | [`DBConnAPIRetrieveResource`](../authentication-authorization.md#authorization-enforcement) |
| **Idempotent** | Yes (read-only; see side effects) |
| **Operation** | OP-04 — see [Operations and processes](../operations-processes.md) |

### Parameters (Oracle)

| Name | In | Type | Required | Default | Binding | Purpose |
| --- | --- | --- | --- | --- | --- | --- |
| `instance` | Query | `string` | No* | — | Inferred by `[ApiController]` (simple type, no route token) | Oracle instance used in the secure-setting key and template |
| `userName` | Query | `string` | No* | — | Inferred by `[ApiController]` | User name used in the secure-setting key |

Both values bind from the query string even though the verb is `POST`. Nullable reference types are disabled, so no implicit required validation applies*; a missing value binds as `null`.

### Response (Oracle)

| Field | Value |
| --- | --- |
| **DTO** | None — `Dictionary<string, string>` |
| **Media type** | `application/json` (JSON object; serializer decided by the opaque base**) |

| Key | Type | Nullable | Purpose |
| --- | --- | --- | --- |
| `credentials` | `string` | Yes** | Raw decrypted secure-setting value (user name and password joined by a pipe character) |
| `user` | `string` | No | Text before the first pipe; empty when the split fails |
| `pw` | `string` | No | **Plaintext password** — text after the first pipe; empty when the split fails |
| `connectionString` | `string` | No | Template with the user and password substituted |
| `Error` | `string` | Present only on split failure | Fixed message stating a pipe delimiter is expected |

### Status codes (Oracle)

| Status | Condition | Body |
| --- | --- | --- |
| `200 OK` | Credential read and split, or split failed and was swallowed ([BR-DBC-023](../business-rules.md#br-dbc-023-admin-inspection-discloses-raw-credentials), [BR-DBC-024](../business-rules.md#br-dbc-024-admin-split-failure-reported-with-status-200)) | JSON object above |

| Error status | Trigger | Produced by | Body |
| --- | --- | --- | --- |
| `401 Unauthorized` / `403 Forbidden` | Caller lacks `DBConnAPIRetrieveResource` ([BR-DBC-025](../business-rules.md#br-dbc-025-resource-authorization-on-every-endpoint)); the exact status is not stated in package documentation** | `[SecurityApiAuthorize]` via the opaque authorization pipeline † | Not visible in source** |
| `500` ** | The secure setting does not exist: the action has no existence check, so the read fails | Opaque package middleware** | Not visible in source** |

No status code is declared with `[ProducesResponseType]`; every non-200 status is undeclared.

### Authorization (Oracle)

Requires resource `DBConnAPIRetrieveResource`, applied at controller level, with no `[AllowAnonymous]` override. This is the same resource that protects the retrieval endpoints, so there is no separate administrative requirement. See [Authentication and authorization](../authentication-authorization.md).

### Side effects and idempotency (Oracle)

| Aspect | Finding |
| --- | --- |
| Records written | None |
| Downstream calls | SAIF Environment API through `IEnvironmentClient` (secure-setting read) |
| Files or messages produced | None |
| Repeat-call behavior | Same result each call: no cache is read or written and no probe runs ([BR-DBC-023](../business-rules.md#br-dbc-023-admin-inspection-discloses-raw-credentials)). Admin requests are not audit-logged |

### Example (Oracle)

```http
POST /v1/Admin/GetOracleConnectionInfo?instance=<instance>&userName=<userName> HTTP/1.1
Host: <host>
Authorization: ******
```

```http
HTTP/1.1 200 OK
Content-Type: application/json

{
  "credentials": "<user>|<password>",
  "user": "<user>",
  "pw": "<password>",
  "connectionString": "<composed connection string>"
}
```

---

## POST v1 Admin GetPostgresConnectionInfo

Returns the decrypted credential parts and the composed connection string for a PostgreSQL server, instance and user name.

| Field | Value |
| --- | --- |
| **HTTP verb** | `POST` |
| **Resolved route** | `/v1/Admin/GetPostgresConnectionInfo` |
| **Route composition** | Class-level `[Route]` template + bare `[HttpPost]`, with the controller-name token resolved to `Admin` and the action token to `GetPostgresConnectionInfo` |
| **Action** | `GetPostgresConnectionInfo` |
| **Return type** | `Dictionary<string, string>` |
| **Declared responses** | None |
| **Authorization** | [`DBConnAPIRetrieveResource`](../authentication-authorization.md#authorization-enforcement) |
| **Idempotent** | Yes (read-only) |
| **Operation** | OP-05 — see [Operations and processes](../operations-processes.md) |

### Parameters (PostgreSQL)

| Name | In | Type | Required | Default | Binding | Purpose |
| --- | --- | --- | --- | --- | --- | --- |
| `server` | Query | `string` | No* | — | Inferred by `[ApiController]` | Server substituted into the template |
| `instance` | Query | `string` | No* | — | Inferred by `[ApiController]` | Instance used in the secure-setting key and template |
| `userName` | Query | `string` | No* | — | Inferred by `[ApiController]` | User name used in the secure-setting key |

The PostgreSQL secure-setting key has no server component, so one credential serves every server for an instance and user ([BR-DBC-006](../business-rules.md#br-dbc-006-postgresql-credentials-ignore-the-server)).

### Response (PostgreSQL)

| Field | Value |
| --- | --- |
| **DTO** | None — `Dictionary<string, string>` |
| **Media type** | `application/json` (serializer decided by the opaque base**) |

The keys are identical to those on [`POST /v1/Admin/GetOracleConnectionInfo`](#post-v1-admin-getoracleconnectioninfo): `credentials`, `user`, `pw`, `connectionString` and, on split failure, `Error`.

### Status codes (PostgreSQL)

| Status | Condition | Body |
| --- | --- | --- |
| `200 OK` | Credential read and split, or split failed and was swallowed ([BR-DBC-023](../business-rules.md#br-dbc-023-admin-inspection-discloses-raw-credentials), [BR-DBC-024](../business-rules.md#br-dbc-024-admin-split-failure-reported-with-status-200)) | JSON object |

| Error status | Trigger | Produced by | Body |
| --- | --- | --- | --- |
| `401 Unauthorized` / `403 Forbidden` | Caller lacks `DBConnAPIRetrieveResource` ([BR-DBC-025](../business-rules.md#br-dbc-025-resource-authorization-on-every-endpoint)); exact status not stated in package documentation** | `[SecurityApiAuthorize]` via the opaque authorization pipeline † | Not visible in source** |
| `500` ** | The secure setting does not exist (no existence check) | Opaque package middleware** | Not visible in source** |

### Authorization (PostgreSQL)

Requires resource `DBConnAPIRetrieveResource` (controller level). See [Authentication and authorization](../authentication-authorization.md).

### Side effects and idempotency (PostgreSQL)

| Aspect | Finding |
| --- | --- |
| Records written | None |
| Downstream calls | SAIF Environment API through `IEnvironmentClient` |
| Files or messages produced | None |
| Repeat-call behavior | Same result each call; no cache, no probe, no audit log |

### Example (PostgreSQL)

```http
POST /v1/Admin/GetPostgresConnectionInfo?server=<server>&instance=<instance>&userName=<userName> HTTP/1.1
Host: <host>
Authorization: ******
```

```http
HTTP/1.1 200 OK
Content-Type: application/json

{
  "credentials": "<user>|<password>",
  "user": "<user>",
  "pw": "<password>",
  "connectionString": "<composed connection string>"
}
```

---

## POST v1 Admin GetSqlConnectionInfo

Returns the decrypted credential parts and the composed connection string for a SQL Server server, instance and user name.

| Field | Value |
| --- | --- |
| **HTTP verb** | `POST` |
| **Resolved route** | `/v1/Admin/GetSqlConnectionInfo` |
| **Route composition** | Class-level `[Route]` template + bare `[HttpPost]`, with the controller-name token resolved to `Admin` and the action token to `GetSqlConnectionInfo` |
| **Action** | `GetSqlConnectionInfo` |
| **Return type** | `Dictionary<string, string>` |
| **Declared responses** | None |
| **Authorization** | [`DBConnAPIRetrieveResource`](../authentication-authorization.md#authorization-enforcement) |
| **Idempotent** | Yes (read-only) |
| **Operation** | OP-06 — see [Operations and processes](../operations-processes.md) |

### Parameters (SQL Server)

| Name | In | Type | Required | Default | Binding | Purpose |
| --- | --- | --- | --- | --- | --- | --- |
| `server` | Query | `string` | No* | — | Inferred by `[ApiController]` | Server used in the secure-setting key and template |
| `instance` | Query | `string` | No* | — | Inferred by `[ApiController]` | Instance used in the secure-setting key and template |
| `userName` | Query | `string` | No* | — | Inferred by `[ApiController]` | User name used in the secure-setting key |

### Response (SQL Server)

| Field | Value |
| --- | --- |
| **DTO** | None — `Dictionary<string, string>` |
| **Media type** | `application/json` (serializer decided by the opaque base**) |

The keys are identical to those on [`POST /v1/Admin/GetOracleConnectionInfo`](#post-v1-admin-getoracleconnectioninfo).

### Status codes (SQL Server)

| Status | Condition | Body |
| --- | --- | --- |
| `200 OK` | Credential read and split, or split failed and was swallowed ([BR-DBC-023](../business-rules.md#br-dbc-023-admin-inspection-discloses-raw-credentials), [BR-DBC-024](../business-rules.md#br-dbc-024-admin-split-failure-reported-with-status-200)) | JSON object |

| Error status | Trigger | Produced by | Body |
| --- | --- | --- | --- |
| `401 Unauthorized` / `403 Forbidden` | Caller lacks `DBConnAPIRetrieveResource` ([BR-DBC-025](../business-rules.md#br-dbc-025-resource-authorization-on-every-endpoint)); exact status not stated in package documentation** | `[SecurityApiAuthorize]` via the opaque authorization pipeline † | Not visible in source** |
| `500` ** | The secure setting does not exist (no existence check) | Opaque package middleware** | Not visible in source** |

### Authorization (SQL Server)

Requires resource `DBConnAPIRetrieveResource` (controller level). See [Authentication and authorization](../authentication-authorization.md).

### Side effects and idempotency (SQL Server)

| Aspect | Finding |
| --- | --- |
| Records written | None |
| Downstream calls | SAIF Environment API through `IEnvironmentClient` |
| Files or messages produced | None |
| Repeat-call behavior | Same result each call; no cache, no probe, no audit log |

### Example (SQL Server)

```http
POST /v1/Admin/GetSqlConnectionInfo?server=<server>&instance=<instance>&userName=<userName> HTTP/1.1
Host: <host>
Authorization: ******
```

```http
HTTP/1.1 200 OK
Content-Type: application/json

{
  "credentials": "<user>|<password>",
  "user": "<user>",
  "pw": "<password>",
  "connectionString": "<composed connection string>"
}
```

---

## Related documentation
- [API index](../index.md)
- [Overview](../overview.md)
- [Architecture](../architecture.md)
- [Hosting pipeline](../hosting-pipeline.md)
- [Endpoints](../endpoints.md)
- [Authentication and authorization](../authentication-authorization.md)
- [Dependencies](../dependencies.md)
- [Configuration](../configuration.md)
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [Data model](../data-model.md)
- [Operational runbook](../operational-runbook.md)
- [Tech debt](../tech-debt.md)

> **Note:** Statements marked with `†` are derived from dependency library
> documentation via the Legends CLI. Statements marked with `*` were inferred
> from code structure or contextual evidence. Statements marked with `**` could
> not be confirmed; treat as unknown until verified.

## Sources
- DBConnectionAPI/DBConnectionAPI/Controllers/AdminController.cs
- DBConnectionAPI/DBConnectionAPI/Services/ConnectionManager.cs
- DBConnectionAPI/DBConnectionAPI/Services/IConnectionManager.cs
- DBConnectionAPI/DBConnectionAPI/EnvironmentKeys.cs
